home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
417_02
/
unzip.tz
/
unzip
/
unz50p1
/
mapname.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-12
|
16KB
|
375 lines
/*---------------------------------------------------------------------------
mapname.c
This routine changes DEC-20, VAX/VMS, and DOS-style filenames into normal
Unix names (and vice versa, in some cases); it also creates any necessary
directories, if the -d switch was specified.
---------------------------------------------------------------------------
Notes:
- This routine REALLY needs to be rewritten (different routines for
each output OS, with different rules for different parts of the path
name). If each zip program stores local-format names (like the VMS
one did at one time), it would probably be best to convert to an in-
termediate format first (assuming we're not extracting under the same
OS as that under which the zipfile was created), then from that to
the current operating system's format.
- The strcpy and strcat operations on both cdp and filename may over-
write memory, since they don't check lengths. With a kilobyte in
which to work, this is probably not that big a deal, but it could
cause problems eventually.
---------------------------------------------------------------------------*/
#include "unzip.h"
/*******************/
/* Mapname Defines */
/*******************/
#ifdef VMS
# define PERMS 0
#else
# define PERMS 0777
#endif
#ifndef NO_MKDIR
# if (defined(DOS_OS2) && !defined(__GO32__))
# if (_MSC_VER >= 600) /* have special MSC mkdir prototype */
# include <direct.h>
# else /* own prototype because dir.h conflicts? */
int mkdir(const char *path);
# endif /* ?(MSC 6.0 or later) */
# define MKDIR(path,mode) mkdir(path)
# else /* !DOS_OS2 || __GO32__ */
# ifdef MACOS
# define MKDIR(path,mode) macmkdir(path,gnVRefNum,glDirID)
# else /* !MACOS */
# define MKDIR(path,mode) mkdir(path,mode)
# endif /* ?MACOS */
# endif /* ?(DOS_OS2 && !__GO32__) */
#endif /* !NO_MKDIR */
/************************/
/* Function mapname() */
/************************/
int mapname(create_dirs) /* return 0 if no error, 1 if caution (filename */
int create_dirs; /* truncated), 2 if warning (skip file because */
{ /* dir doesn't exist), 3 if error (skip file) */
#ifdef NO_MKDIR
char command[FILNAMSIZ+40]; /* buffer for system() call */
#endif
#ifdef VMS
int stat_val; /* temp. holder for stat() return value */
char *dp, *xp; /* pointers to directory name */
char *np; /* pointer into filename */
#endif /* VMS */
#ifdef DOS_VMS
char *last_dot=NULL; /* last dot not converted to underscore */
#endif /* DOS_VMS */
#ifdef OS2
char *last;
extern char longfilename[]; /* AFTER file created and closed */
extern int longname; /* used also in file_io.c: set EAs */
int longdir;
#endif /* OS2 */
char name[FILNAMSIZ]; /* file name buffer */
char *pp, *cp, *cdp; /* character pointers */
char delim = '\0'; /* directory delimiter */
int quote = FALSE; /* flags */
int indir = FALSE;
int done = FALSE;
int created = FALSE;
register unsigned workch; /* hold the character being tested */
/*---------------------------------------------------------------------------
Initialize various pointers and counters and stuff.
---------------------------------------------------------------------------*/
#ifdef MAP_DEBUG
fprintf(stderr, "%s ", filename); /* echo name of this file */
#endif
cdp = (char *)NULL;
pp = name; /* point to translation buffer */
*name = '\0'; /* initialize buffer */
if (!jflag) { /* -j => junk pathnames */
cdp = (char *)malloc(strlen(filename) + 3); /* place for holding */
if (cdp == (char *)NULL) { /* directory name */
fprintf(stderr, "mapname: out of memory [%s]\n", filename);
return 3;
}
#ifdef VMS
*cdp++ = '[';
xp = cdp; /* always points to last non-NULL char */
*cdp++ = '.';
#endif /* VMS */
#ifdef MACOS
*cdp = ':'; /* the Mac uses ':' as a directory separator */
cdp[1] = '\0';
#else /* !MACOS */
*cdp = '\0';
#endif /* ?MACOS */
}
/*---------------------------------------------------------------------------
Begin main loop through characters in filename.
---------------------------------------------------------------------------*/
for (cp = filename; (workch = (unsigned char) *cp++) != 0 && !done;) {
if (quote) { /* if char quoted, */
*pp++ = (char) workch; /* include it literally */
quote = FALSE;
} else if (indir) { /* if in directory name, */
if (workch == (unsigned)delim) /* look for end delimiter */
indir = FALSE;
} else
switch (workch) {
case '<': /* discard DEC-20 directory name */
indir = TRUE;
delim = '>';
break;
case '[': /* discard VMS directory name */
indir = TRUE;
delim = ']';
break;
case '/': /* discard Unix path name */
case '\\': /* or MS-DOS path name... */
/* iff -j flag was given */
/*
* Special processing case: if -j flag was not specified on
* command line and create_dirs is TRUE, create any necessary
* directories included in the pathname. Creation of dirs is
* straightforward on BSD and MS-DOS machines but requires use
* of the system() command on SysV systems (or any others which
* don't have mkdir()). The stat() check is necessary with
* MSC because it doesn't have an EEXIST errno, and it saves
* the overhead of multiple system() calls on SysV machines.
*/
if (!jflag) {
*pp = '\0';
#ifdef VMS
dp = name;
while (*++xp = *dp++); /* copy name to cdp */
last_dot = NULL; /* dir name: no dots allowed */
strcpy(xp, ".dir"); /* add extension for stat check */
stat_val = stat(cdp, &statbuf);
*xp = '\0'; /* remove extension for all else */
if (stat_val) { /* doesn't exist, so create */
#else /* !VMS */
#ifdef MSDOS
if (last_dot != NULL) { /* one dot in dir name is legal */
*last_dot = '.';
last_dot = NULL;
}
#endif /* MSDOS */
strcat(cdp, name);
#ifdef OS2
if ((longdir = !IsFileNameValid(cdp)) != 0) {
last = strrchr(cdp, '/');
strcpy(longfilename, last ? last + 1 : cdp);
fprintf(stderr, "renaming directory \"%s\"", cdp);
ChangeNameForFAT(cdp);
fprintf(stderr, " to \"%s\"\n", cdp);
}
#endif /* OS2 */
if (stat(cdp, &statbuf)) { /* doesn't exist, so create */
#endif /* ?VMS */
if (!create_dirs) /* told not to create (freshening) */
return 2;
#ifdef NO_MKDIR
sprintf(command,
"IFS=\" \t\n\" /bin/mkdir %s 2>/dev/null", cdp);
if (system(command)) {
#else /* !NO_MKDIR */
if (MKDIR(cdp, PERMS) == -1) {
#endif /* ?NO_MKDIR */
perror(cdp);
free(cdp);
fprintf(stderr, "mapame: unable to process [%s]\n",
filename);
return 3;